#include "xstring.h"
#include "autodelete.hpp"
#include "common.h"

#include <cstring>
#include <cstdio>

u8string &u8string::fromUTF16(const wchar_t *p)
{
    clear();
    int size = wcslen(p) + 1;

    int new_size = ::WideCharToMultiByte(CP_UTF8, 0, p, size, NULL, 0, NULL, NULL);
    if (!new_size)
    {
        E("WideCharToMultiByte");
        return *this;
    }
    AutoDeletes<char> q(new char[new_size]);
    new_size = ::WideCharToMultiByte(CP_UTF8, 0, p, size, q, new_size, NULL, NULL);
    if (!new_size)
    {
        E("WideCharToMultiByte");
        return *this;
    }
    m_ptr = q.move();
    m_len = new_size;
    return *this;
}
u8string &u8string::fromAnsi(const char *p)
{
    clear();
    int size = strlen(p) + 1;

    int new_size = ::MultiByteToWideChar(CP_ACP, 0, p, size, NULL, 0);
    if (!new_size)
    {
        E("MultiByteToWideChar");
        return *this;
    }
    AutoDeletes<wchar_t> q(new wchar_t[new_size]);
    new_size = ::MultiByteToWideChar(CP_ACP, 0, p, size, q, new_size);
    if (!new_size)
    {
        E("MultiByteToWideChar");
        return *this;
    }
    return fromUTF16(q);
}
u8string &u8string::FormatV(const char *fmt, va_list ap)
{
    clear();

    int len = _vscprintf(fmt, ap);
    if(len < 0)
        return *this;

    size_t size = (size_t)len + 1;
    AutoDeletes<char> p(new char[size]);
    if(!p)
        return *this;
    len = vsprintf_s(p, size, fmt, ap);
    if(len < 0)
        return *this;
    return fromAnsi(p);
}
u8string &u8string::FormatV(const wchar_t *fmt, va_list ap)
{
    clear();

    int len = _vscwprintf(fmt, ap);
    if(len < 0)
        return *this;

    size_t size = (size_t)len + 1;
    AutoDeletes<wchar_t> p(new wchar_t[size]);
    if(!p)
        return *this;
    len = vswprintf_s(p, size, fmt, ap);
    if(len < 0)
        return *this;
    return fromUTF16(p);
}
u8string &u8string::Append(const char *str)
{
    u8string t;
    *this += t.fromAnsi(str);
    return *this;
}

u8string &u8string::Append(const wchar_t *str)
{
    u8string t;
    *this += t.fromUTF16(str);
    return *this;
}
